
<head>
    <title>Proof of Concept: CIM Access</title>
    <meta charset="utf-8">
    <link href="../base1/cockpit.css" type="text/css" rel="stylesheet">
    <script src="../base1/cockpit.js"></script>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
    <div class="pf-c-page">
        <main class="pf-c-page__main" tabindex="-1">
            <section class="pf-c-page__main-section pf-m-light">
                <h2>Proof of Concept: CIM Access</h2>

                <p>This is a proof of concept for accessing CIM data via Pegasus in Cockpit.</p>

                <p><button class="pf-c-button pf-m-secondary pf-m-primary" id="process">Process List</button>
                <span id="message" class="warning" hidden></span></p>

                <table class="table table-hover" style="font-size: 11px" hidden>
                    <thead>
                        <tr>
                            <td>PID</td>
                            <td>Name</td>
                            <td>UID</td>
                            <td>Priority</td>
                        </tr>
                    </thead>
                    <tbody>
                    </tbody>
                </table>
            </section>
        </main>
    </div>

    <script>
        $("#process").on("click", function() {
            var params = '<IPARAMVALUE NAME="ClassName"><CLASSNAME NAME="PG_UnixProcess"/></IPARAMVALUE>';
            request("EnumerateInstances", params);
        });

        var http = cockpit.http("/run/tog-pegasus/cimxml.socket", {
                connection: "cim-" + new Date().getTime(),
        });

        function message(str) {
            $("#message").text(str).show();
        }

        function display(data) {
            var response = new DOMParser().parseFromString(data, "application/xml");

            var tbody = $("tbody");
            tbody.empty();

            var error = $(response).find('ERROR');
            if (error.length) {
                message(error.attr("DESCRIPTION") || error);
                return;
            }

            var instances = response.getElementsByTagName("INSTANCE");

            /* Wheee */
            $("table").show();
            message("Done! " + instances.length + " processes, " + data.length + " bytes transferred from CIM ");

            $(response).find("INSTANCE").each(function() {
                tbody.append(
                    $("<tr>").append(
                        $("<td>").text($(this).find('[NAME="Handle"]').text()),
                        $("<td>").text($(this).find('[NAME="Name"]').text()),
                        $("<td>").text($(this).find('[NAME="RealUserID"]').text()),
                        $("<td>").text($(this).find('[NAME="Priority"]').text())
                    )
                );
            });
        }

        var message_id = 1001;
        function request(method, params, token) {
            message("...");

            var headers = {
                "Content-Type": "application/xml; charset=\"utf-8\"",
                "CIMOperation": "MethodCall",
                "CIMMethod": method,
                "CIMObject": "root/cimv2"
            };

            cockpit.user().done(function (user) {
                var auth = "Local \"" + user;
                if (token)
                    auth += ":" + token;
                auth += "\"";
                headers["PegasusAuthorization"] = auth;

                body = '<?xml version="1.0" encoding="utf-8" ?>\n' +
                       '<CIM CIMVERSION="2.0" DTDVERSION="2.0"><MESSAGE ID="' + message_id +
                       '" PROTOCOLVERSION="1.0"><SIMPLEREQ><IMETHODCALL NAME="' + method + '">' +
                       '<LOCALNAMESPACEPATH><NAMESPACE NAME="root"/><NAMESPACE NAME="cimv2"/></LOCALNAMESPACEPATH>' +
                       params + '</IMETHODCALL></SIMPLEREQ></MESSAGE></CIM>\n';
                message_id += 1;

                var authenticating = false;
                http.post("/cimom", body, headers)
                    .response(function(status, headers) {
                        if (token)
                            return;
                        var header = headers["WWW-Authenticate"];
                        if (!header || header.indexOf("Local ") !== 0) {
                            message("Missing header WWW-Authenticate: Local ...");
                        } else {
                            authenticating = true;
                            var filename = header.substring(7, header.length - 1);
                            cockpit.file(filename).read()
                                .done(function(data) {
                                    request(method, params, filename + ":" + $.trim(data));
                                })
                                .fail(function(ex) {
                                    message(filename + ": " + ex.message);
                                });
                        };
                    })
                    .done(display)
                    .fail(function(ex) {
                        if (!authenticating)
                            message(method + ": " + ex.message);
                    });
            });
        }

    </script>
</body>
</html>

